#include "levelstate.h"

void LevelState::ClientInit()
{
	m_work_manager = m_client->work_manager();
	m_guid = m_client->GetGUID();
}

void LevelState::ClientCleanup()
{
	if (m_shutdown_network_on_state_end)
	{
		m_client->Shutdown();
		delete m_client;
	}
}

void LevelState::DoClientWork()
{
	Job next_job;
	while (m_work_manager->GetJobToLocal(next_job))
	{
		unsigned char type_id;
		next_job.data->Read(type_id);
		switch (type_id)
		{
		case ID_DISCONNECTION_NOTIFICATION:
		case ID_CONNECTION_LOST:
			ClientProcessClosedConnection();
			break;

		case ID_REMOVE_CLIENT:
			ClientProcessRemoveClient(next_job);
			break;

		case ID_OPEN_ENTRIES:
			ClientProcessOpenEntries();
			break;

		case ID_START_SPAWN:
			ClientProcessStartSpawn();
			break;
		};

		next_job.JobDone();
	}
}

void LevelState::ClientProcessClosedConnection()
{
	// We have been disconnected.
	// TODO: Do something that makes sense (i.e. state change, ...)
	m_shutdown_network_on_state_end = true;
	m_engine->set_end_game(true);
}

void LevelState::ClientProcessRemoveClient(Job remove_client_job)
{
	RakNet::RakString guid_string;
	RakNet::StringCompressor::Instance()->DecodeString(&guid_string, 64, remove_client_job.data);
	m_client_list.RemoveClient(std::string(guid_string.C_String()));
}

void LevelState::ClientProcessOpenEntries()
{
	if (!m_opened)
	{
		m_opened = true;
		m_level->OpenEntries();
	}
}

void LevelState::ClientProcessStartSpawn()
{
	if (!m_release_started)
	{
		m_release_started = true;
		m_level->StartToRelease();
	}
}

void LevelState::ClientUpdate(float timing_factor)
{
	DoClientWork();
}